//============================================================================
// Copyright (C) 2009-2013 Brett R. Jones
//
// Issued to public domain 2013
//
// brettjones1900@gmail.com
// http://www.p2panarchy.com
//============================================================================

#include "OnlineId.h"
#include "VxParse.h"

//============================================================================
OnlineId::OnlineId()
: m_u64IdHiPart(0)
, m_u64IdLoPart(0)
{
}

//============================================================================
//=== constructor ===//
OnlineId::OnlineId( U64 u64HiPart, U64 u64LoPart )
: m_u64IdHiPart(u64HiPart)
, m_u64IdLoPart(u64LoPart)
{
}

//============================================================================
//=== methods ===//
//! copy operator
OnlineId & OnlineId::operator =( const OnlineId &a )
{
	// Check for self-assignment!
	if (this != &a)      // Same object?
	{
		// Not same object so copy
		m_u64IdHiPart = a.m_u64IdHiPart;
		m_u64IdLoPart = a.m_u64IdLoPart;
	}
	return *this;
}

//============================================================================
//! equals operator
bool OnlineId::operator == ( const OnlineId &a ) const
{
	return ((m_u64IdLoPart == a.m_u64IdLoPart ) && (m_u64IdHiPart == a.m_u64IdHiPart ));
}

//============================================================================
//! not equal operator
bool OnlineId::operator != ( const OnlineId &a ) const
{
	return !(*this == a);
}

//============================================================================
//! less than operator
bool OnlineId::operator < ( const OnlineId &b ) const
{
	if( m_u64IdHiPart < b.m_u64IdHiPart )
		return true;
	if( m_u64IdHiPart == b.m_u64IdHiPart )
		if( m_u64IdLoPart < b.m_u64IdLoPart )
			return true;
	return false;

}

//============================================================================
//! return true if valid id
bool		OnlineId::isOnlineIdValid()	const						{ return ((m_u64IdLoPart != 0 ) && (m_u64IdHiPart != 0 ));}

//============================================================================
//! return id as string
void		OnlineId::toOnlineIdHexString( std::string& strRetId )	
{ 
	return StdStringFormat( strRetId, "%llx%llx", m_u64IdHiPart, m_u64IdLoPart ); 
} 

//============================================================================
static U8 charToHex( char cVal )
{
	if( cVal >= '0' && cVal <= '9' )
	{
		return cVal & 0x0f;
	}
	return cVal - 87;
}

//============================================================================
//! set online id by converting hex string into U128
void OnlineId::fromOnlineIdHexString( const char * pHexString )
{
	U8 u8Byte;
	U64 u64Part = 0;
	for( int i = 0; i < 8; i++ )
	{
		u64Part = u64Part << 8;
		u8Byte = (charToHex(*pHexString))<<4;
		pHexString++;
		u8Byte |= charToHex(*pHexString);
		pHexString++;
		u64Part |= u8Byte;

	}
	m_u64IdHiPart = u64Part;
	u64Part = 0;
	for( int i = 0; i < 8; i++ )
	{
		u64Part = u64Part << 8;
		u8Byte = (charToHex(*pHexString))<<4;
		pHexString++;
		u8Byte |= charToHex(*pHexString);
		pHexString++;
		u64Part |= u8Byte;
	}
	m_u64IdLoPart = u64Part;
}

//============================================================================
//! get low part of online id
U64&		OnlineId::getOnlineIdLoPart()								{ return m_u64IdLoPart; }

//============================================================================
//! get high part of online id
U64&		OnlineId::getOnlineIdHiPart()								{ return m_u64IdHiPart; }

//============================================================================
//! return users online id
OnlineId&	OnlineId::getOnlineId( void )								{ return *this; }

//============================================================================
//! return users online id as string
void		OnlineId::getOnlineId( std::string& strRetId )			{ return this->toOnlineIdHexString( strRetId ); }

//============================================================================
//! set users online id
void		OnlineId::setOnlineId( OnlineId& oId )					{ *this = oId; }

//============================================================================
//! set users online id
void		OnlineId::setOnlineId( U64& u64HiPart, U64& u64LoPart )	{ m_u64IdHiPart = u64HiPart; m_u64IdLoPart = u64LoPart; }

//============================================================================
//! get users online as 2 parts
void		OnlineId::getOnlineId( U64& u64HiPart, U64& u64LoPart )	{  u64HiPart = m_u64IdHiPart; u64LoPart = m_u64IdLoPart; }

//============================================================================
//! set users online id
void		OnlineId::setOnlineId( const char * pId )					{ this->fromOnlineIdHexString( pId ); }

//////////////////////////////////////////////////////////////////////////////
std::string	OnlineId::describeOnlineId( void )
{
	std::string strId;
	StdStringFormat( strId, " 0x%llx 0x%llx ", m_u64IdHiPart, m_u64IdLoPart);
	return strId;
}